unit uFormMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  uPluginIntf, StdCtrls, Dialogs,
  DrcpSvc, ComCtrls, JvExComCtrls,
  JvComCtrls, JvCheckTreeView, ImgList;

type
  TForm_Main = class(TForm,IPluginable)
    ListBox_Roles: TListBox;
    Label1: TLabel;
    Label5: TLabel;
    Edit_Name: TEdit;
    Label6: TLabel;
    Memo_Description: TMemo;
    Button_Update: TButton;
    Button_Delete: TButton;
    Label7: TLabel;
    Button_Refresh: TButton;
    JvCheckTreeView1: TJvCheckTreeView;
    ImageList1: TImageList;
    Label2: TLabel;
    Edit_Id: TEdit;
    Button_New: TButton;
    procedure FormDestroy(Sender: TObject);
    procedure Button_RefreshClick(Sender: TObject);
    procedure ListBox_RolesClick(Sender: TObject);
    procedure Button_DeleteClick(Sender: TObject);
    procedure Button_UpdateClick(Sender: TObject);
    procedure Button_NewClick(Sender: TObject);
  private
    FSoapAddr : string;
    FSoap : DrcpService;
    { Private declarations }

    function GetCurSelectedRole : Role;
    procedure LoadRoleList;

    procedure ClearListWithObject(AList : TStrings);
  protected
    FModeCreateNew : Boolean;
    FPlugin : IPlugin;

    procedure SetPlugin(APlugin : IPlugin);
    function GetPlugin:IPlugin;

    procedure ClearFunctionTree;
    procedure UpdateFunctionTree;
    procedure LoadChildrenNode(Tree : TJvTreeView;node : TJvTreeNode; AFunctionId : string);

    procedure RefreshFunctionTreeChecked;
    function GetFunctionTreeCheckedIds:ArrayOf_xsd_string;

    procedure Init;
  public


    { Public declarations }
    property Plugin : IPlugin read GetPlugin write SetPlugin;
  end;

var
  Form_Main: TForm_Main;
implementation

{$R *.dfm}

procedure TForm_Main.Init;
var
  lClientConfig : TStrings;
  lPrintPort : String;
begin
  { TODO -oyou -cplugin-template : fill initialization code here }

  //how to get client-config
  lClientConfig := TStringList.Create;
  lClientConfig.Text := Plugin.HostParams;

  lPrintPort := lClientConfig.Values['Port'];

  lClientConfig.Free;


  //how to get soap address by context variable, see more RS_xxx by CTL + LeftClick
  FSoapAddr := Plugin.Variable[RS_DEFAULT_CONTAINER_SOAP_ADDR];
  FSoap := GetDrcpService(false,FSoapAddr);

  //how to get initialzation info
  //Plugin.InitString can be any string, strore in db [module.initstring]

  LoadRoleList;
end;

procedure TForm_Main.FormDestroy(Sender: TObject);
var
  lClientConfig : TStrings;
begin
  lClientConfig := TStringList.Create;
  lClientConfig.Values['Port'] := 'LPT1';
  lClientConfig.Values['X'] := '0';
  lClientConfig.Values['Y'] := '1';

  Plugin.HostParams := lClientConfig.Text;  //save to db

  lClientConfig.Free;

  { TODO -oyou -cplugin-template : fill finalization code here }

end;

procedure TForm_Main.Button_RefreshClick(Sender: TObject);
begin
  LoadRoleList;
end;

procedure TForm_Main.ListBox_RolesClick(Sender: TObject);
var
  I : integer;
  lRole : Role;

begin
  lRole := GetCurSelectedRole;

  Edit_Id.Text := lRole.id;
  Edit_Name.Text := lRole.name;
  Memo_Description.Lines.Text := lRole.description;

  //get function info
  //build funcion tree, and set the checkbox
  UpdateFunctionTree;

end;

procedure TForm_Main.Button_DeleteClick(Sender: TObject);
var
  lRole : Role;
begin
  lRole := GetCurSelectedRole;
  FSoap.Role_Delete(lRole.id);

  LoadRoleList;
end;

procedure TForm_Main.LoadRoleList;
var
  I : integer;
  lRole : Role;
  lAllRoles : ArrayOf_tns2_Role;
begin

  ClearListWithObject(ListBox_Roles.Items);

  lAllRoles := FSoap.Role_GetAll;
  for I := 0 to Length(lAllRoles) -1 do
  begin
    lRole := lAllRoles[I];
    ListBox_Roles.Items.AddObject(lRole.name,lRole);
  end;
end;

procedure TForm_Main.Button_UpdateClick(Sender: TObject);
var
  lRole : Role;
  I : integer;
  lCheckedFuncIds : ArrayOf_xsd_string;
begin
  lRole := Role.Create;

  lRole.id := Edit_Id.Text;
  lRole.name := Edit_name.Text;
  lRole.description := Memo_Description.Lines.Text;

  FSoap.Role_Update(lRole);

  //update role-function
  lCheckedFuncIds := GetFunctionTreeCheckedIds;
  FSoap.FunctionAuthorization_SetAuthorizedFunctions(lRole.id,lCheckedFuncIds);

  LoadRoleList;
end;

function TForm_Main.GetCurSelectedRole: Role;
begin
  Result := Role(ListBox_Roles.Items.Objects[ListBox_Roles.ItemIndex]);
end;

procedure TForm_Main.ClearListWithObject(AList: TStrings);
var
  I : integer;
begin
  for I := 0 to AList.Count -1 do
    (AList.Objects[I]).Free;

  AList.Clear;
end;

procedure TForm_Main.LoadChildrenNode(Tree: TJvTreeView; node: TJvTreeNode;
  AFunctionId: string);
var
  lc,
  lfunc : Function_;
  lchildren : ArrayOf_tns2_Function;
  i : integer;
  lcnode : TJvTreeNode;

  lNodeIsAuthorized : boolean;
begin

  lchildren := FSoap.Function_GetChildren(AFunctionId);
  for i := 0 to length(lchildren) -1 do
  begin
    lc := lchildren[i];

    lcnode:= (Tree.Items.AddChildObject(node,lc.name,lc) as TJvTreeNode);

    if UpperCase(lc.typeId) = UpperCase('module') then
    begin
      lcnode.ImageIndex := 1;
      lcnode.SelectedIndex := 1;
    end
    else
    begin
      lcnode.ImageIndex := 0;
      lcnode.SelectedIndex := 0;
    end;
    LoadChildrenNode(Tree,lcnode, lc.id);
  end;

end;

procedure TForm_Main.UpdateFunctionTree;
var
  lfunc : Function_;
begin
  ClearFunctionTree;

  lfunc:=FSoap.Function_GetRoot();
  LoadChildrenNode(JvCheckTreeView1,nil,lfunc.id);

  RefreshFunctionTreeChecked;
end;

procedure TForm_Main.ClearFunctionTree;
var
  i : integer;
  lfunc : Function_;
begin

  for i := 0 to JvCheckTreeView1.Items.Count - 1 do
  begin
    lfunc := Function_(JvCheckTreeView1.Items[i].Data);
    lfunc.Free;
  end;

  JvCheckTreeView1.Items.Clear;

end;

procedure TForm_Main.RefreshFunctionTreeChecked;
  function IndexOfFunc(AFunc : Function_; AAllFuncs : ArrayOf_tns2_Function): integer;
  var
    I : integer;
  begin
    Result := -1;
    
    for I := 0 to Length(AAllFuncs) -1 do
    begin
      if AAllFuncs[I].id = AFunc.id then
      begin
        Result := I;
        Exit;
      end;
    end;
  end;

var
  I : integer;
  lNode : TJvTreeNode;
  lFunc : Function_;
  lAuthorizedFuncs : ArrayOf_tns2_Function;

  lCurRole : Role;
begin

  lCurRole := GetCurSelectedRole;
  if lCurRole = nil then
  begin
    ClearFunctionTree;
    Exit;
  end;

  lAuthorizedFuncs := FSoap.FunctionAuthorization_GetAuthorizedFunctions(GetCurSelectedRole.id);

  for I := 0 to JvCheckTreeView1.Items.Count - 1 do
  begin
    lNode := (JvCheckTreeView1.Items[I] as TJvTreeNode);
    lFunc := Function_(lNode.Data);

    if IndexOfFunc(lFunc,lAuthorizedFuncs) >= 0 then
      lNode.Checked := true
    else
      lNode.Checked := false;

  end;

end;

function TForm_Main.GetFunctionTreeCheckedIds: ArrayOf_xsd_string;
var
  I : integer;
  lNode : TJvTreeNode;
  lFunc : Function_;
  lAuthorizedFuncs : ArrayOf_tns2_Function;

  lIds : TStrings;
begin

  lIds := TStringList.Create;

  for I := 0 to JvCheckTreeView1.Items.Count - 1 do
  begin
    lNode := (JvCheckTreeView1.Items[I] as TJvTreeNode);
    lFunc := Function_(lNode.Data);

    if lNode.Checked then
      lIds.Add(lFunc.id);

  end;

  //output to result
  SetLength(Result, lIds.Count);
  for I := 0 to lIds.Count - 1 do
    Result[I] := lIds.Strings[I];

  lIds.Free;
end;

procedure TForm_Main.Button_NewClick(Sender: TObject);
var
  lRole : Role;
  lId : WideString;
begin
  Edit_Name.Text := 'new name';
  Memo_Description.Lines.Text := 'new description';

  lRole := Role.Create;

  lRole.name := Edit_Name.Text;  
  lRole.description := Memo_Description.Lines.Text;

  //update DB
  lId := FSoap.Role_Save(lRole);
  lRole.id := lId;
  
  //update UI
  ListBox_Roles.Items.AddObject(lRole.name,lRole);
  
end;

function TForm_Main.GetPlugin: IPlugin;
begin
  Result := FPlugin;
end;

procedure TForm_Main.SetPlugin(APlugin: IPlugin);
begin
  FPlugin := APlugin;

  Init;
end;

end.

